/**
 * 属性装饰器
 */

/**
 * @param target 装饰的目标对象，这里就是Person类
 * @param key 装饰的key --> name字段
 */
function logProperty(target: any, key: string) {
  // console.log(target)
  // console.log('key-->', key)

  // 先移除之前初始化的字段，其实也可以不移除
  delete target[key]

  const field = '_' + key

  // 重新在  target 上 定义了一个字段 field
  Object.defineProperty(target, field, {
    writable: true,
    enumerable: true,
    configurable: true
  })

  const getter = function (this: any) {
    console.log(
      `触发getter, 会返回新增的字段（${field}）的值 : `,
      key,
      this[field]
    )

    return this[field]
  }

  const setter = function (this: any, newVal: any) {
    console.log('触发setter--> ', key, newVal)

    this[field] = newVal
  }

  // 劫持这里的 key, 从而触发对我们新增字段的 赋值和取值操作
  Object.defineProperty(target, key, {
    get: getter,
    set: setter,
    enumerable: true,
    configurable: true
  })
}

class Person {
  @logProperty
  public name: string

  constructor(name: string) {
    console.log('Person构造函数执行')

    this.name = name
  }
}

const p: any = new Person('张三')

// 触发name的  setter - 就会将 _name的值赋为新的内容
p.name = '是的，我重新给name赋值了'

// 触发 _name 属性的 getter
console.log(p._name)

// console.log(p.name)
